/**
 * 通用验证 Schema
 * 定义常用的数据格式验证规则
 */

import { Type, Static } from '@sinclair/typebox'

// ==================== 基础类型 ====================

/**
 * UUID 格式验证
 */
export const UUIDSchema = Type.String({
    format: 'uuid',
    description: 'UUID 格式的ID'
})

/**
 * 日期时间格式验证
 */
export const DateTimeSchema = Type.String({
    format: 'date-time',
    description: 'ISO 8601 日期时间格式'
})

/**
 * 邮箱格式验证
 */
export const EmailSchema = Type.String({
    format: 'email',
    minLength: 5,
    maxLength: 255,
    description: '邮箱地址'
})

/**
 * 手机号格式验证（中国）
 */
export const PhoneSchema = Type.String({
    pattern: '^1[3-9]\\d{9}$',
    description: '中国大陆手机号'
})

/**
 * 密码格式验证
 */
export const PasswordSchema = Type.String({
    minLength: 8,
    maxLength: 64,
    description: '密码（8-64个字符）'
})

/**
 * URL 格式验证
 */
export const URLSchema = Type.String({
    format: 'uri',
    description: 'URL 地址'
})

// ==================== 分页参数 ====================

/**
 * 分页查询参数
 */
export const PaginationQuerySchema = Type.Object({
    offset: Type.Optional(
        Type.Integer({
            minimum: 0,
            default: 0,
            description: '偏移量'
        })
    ),
    limit: Type.Optional(
        Type.Integer({
            minimum: 1,
            maximum: 100,
            default: 20,
            description: '每页数量'
        })
    )
})

export type PaginationQuery = Static<typeof PaginationQuerySchema>

// ==================== GPS 坐标 ====================

/**
 * GPS 坐标验证
 */
export const LocationSchema = Type.Object({
    latitude: Type.Number({
        minimum: -90,
        maximum: 90,
        description: '纬度'
    }),
    longitude: Type.Number({
        minimum: -180,
        maximum: 180,
        description: '经度'
    }),
    accuracy: Type.Optional(
        Type.Number({
            minimum: 0,
            maximum: 1000,
            description: '定位精度（米）'
        })
    )
})

export type Location = Static<typeof LocationSchema>

// ==================== 通用响应 ====================

/**
 * 成功响应格式
 */
export const SuccessResponseSchema = Type.Object({
    success: Type.Literal(true, { description: '请求成功标志' }),
    data: Type.Any({ description: '响应数据' }),
    message: Type.Optional(Type.String({ description: '提示信息' })),
    statusCode: Type.Optional(Type.Integer({ description: 'HTTP 状态码' }))
})

/**
 * 错误响应格式
 */
export const ErrorResponseSchema = Type.Object({
    success: Type.Literal(false, { description: '请求失败标志' }),
    error: Type.String({ description: '错误信息' }),
    code: Type.Optional(Type.String({ description: '错误代码' })),
    statusCode: Type.Integer({ description: 'HTTP 状态码' }),
    details: Type.Optional(Type.Any({ description: '详细错误信息' })),
    timestamp: Type.String({ description: '错误发生时间' }),
    path: Type.String({ description: '请求路径' })
})

/**
 * 分页响应格式
 */
export function PaginatedResponseSchema<T>(itemSchema: T) {
    return Type.Object({
        success: Type.Literal(true),
        data: Type.Object({
            data: Type.Array(itemSchema as any),
            total: Type.Integer({ description: '总数量' }),
            offset: Type.Integer({ description: '偏移量' }),
            limit: Type.Integer({ description: '每页数量' }),
            hasMore: Type.Boolean({ description: '是否有更多数据' })
        })
    })
}

// ==================== 常用枚举 ====================

/**
 * 签到状态枚举
 */
export const RecordStatusSchema = Type.Union(
    [
        Type.Literal('PENDING'),
        Type.Literal('PRESENT'),
        Type.Literal('LATE'),
        Type.Literal('ABSENT'),
        Type.Literal('LEAVE_EARLY')
    ],
    {
        description: '签到状态'
    }
)

/**
 * 用户类型枚举
 */
export const UserTypeSchema = Type.Union([Type.Literal('admin'), Type.Literal('member')], {
    description: '用户类型'
})

/**
 * 管理员角色枚举
 */
export const AdminRoleSchema = Type.Union([Type.Literal('GLOBAL_ADMIN'), Type.Literal('ORGANIZATION_ADMIN')], {
    description: '管理员角色'
})

/**
 * 成员角色枚举
 */
export const MemberRoleSchema = Type.Union([Type.Literal('MEMBER'), Type.Literal('MODERATOR')], {
    description: '成员角色'
})
